package org.su.webadapter.interceptor;


import org.su.generalmvc.IEditor;
import org.su.generalmvc.config.BindBeanException;
import org.su.generalmvc.config.UploadConfig;
import org.su.generalmvc.core.ActionInvocation;
import org.su.generalmvc.core.IXsshApplicationContext;
import org.su.generalmvc.core.InitialContext;
import org.su.generalmvc.core.Interceptor;
import org.su.generalmvc.util.ObjectUtils;
import org.su.webadapter.DefaultMultipartHttpServletRequest;
import org.su.webadapter.MultipartHttpServletRequest;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.Map;

/**
 * 参数拦截器，负责将请求数据封装到action的参数列表中
 * 
 * @author yangchuan
 * 
 */
public class ParamInterceptor implements Interceptor {

	protected static final Log logger = LogFactory
			.getLog(ParamInterceptor.class);

	private static ServletFileUpload upload;

	private IXsshApplicationContext context = null;

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	@Override
	public void init() {
		context = InitialContext.getInstance().getContext();
		initFileTool();
	}

	@Override
	public Object intercept(ActionInvocation invocation) throws Exception {
		HttpServletRequest request = (HttpServletRequest)invocation.getRequest();
		HttpServletResponse response = (HttpServletResponse)invocation.getResponse();
		IEditor[] paramBinds = invocation.getProxy().getActionConfig()
				.getParamBinds();
		String[] paramNames = invocation.getProxy().getActionConfig()
				.getParamNames();
		Map<String, Class<?>> beanTypes = invocation.getProxy()
				.getActionConfig().getBeanParams();
		if (!ObjectUtils.isEmpty(paramBinds)) {
			Object[] args = new Object[paramBinds.length];
			if (ServletFileUpload.isMultipartContent(request)) {
				request = prossMultipart(request, response);

			}
			for (int i = 0; i < paramBinds.length; i++) {
				try {
					args[i] = paramBinds[i].getParamValue(paramNames[i],
							beanTypes.get(paramNames[i]),i, invocation.getProxy().getAction(), request, response);
				} catch (Exception e) {
					throw new BindBeanException("binding value for: "
							+ paramNames[i], e);
				}
			}

			invocation.setArgs(args);
		}

		return invocation.invoke();
	}

	/**
	 * 上传处理
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	private MultipartHttpServletRequest prossMultipart(
			HttpServletRequest request, HttpServletResponse response) {

		MultipartHttpServletRequest mrequest = new DefaultMultipartHttpServletRequest(
				request);
		mrequest.initializeMultipart(upload);
		return mrequest;
	}

	private void initFileTool() {
		// if (null == upload) {
		UploadConfig uploadConfig = InitialContext.getInstance().getContext()
				.getConfig().getUploadConfig();
		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setSizeThreshold(uploadConfig.getSizeThreshold());
		File dir = uploadConfig.getRepository();
		if (!dir.exists()) {
			if (!dir.mkdirs()) {
				throw new RuntimeException(dir.getAbsolutePath());
			}
		}
		factory.setRepository(uploadConfig.getRepository());
		upload = new ServletFileUpload(factory);
		upload.setSizeMax(uploadConfig.getSizeMax());
		upload.setHeaderEncoding(context.getConfig().getEncoding());
		/*
		 * 处理进度监听接口 ProgressListener progressListener = new ProgressListener() {
		 * private long megaBytes = -1;
		 * 
		 * public void update(long pBytesRead, long pContentLength, int pItems)
		 * { long mBytes = pBytesRead / 1000000; if (megaBytes == mBytes) {
		 * return; } megaBytes = mBytes;
		 * System.out.println("We are currently reading item " + pItems); if
		 * (pContentLength == -1) { System.out.println("So far, " + pBytesRead +
		 * " bytes have been read."); } else { System.out.println("So far, " +
		 * pBytesRead + " of " + pContentLength + " bytes have been read."); } }
		 * }; upload.setProgressListener(progressListener);
		 */
		// }
	}
}
